<template>
  <div id="app">
    <h3 style="color:rgba(150, 84, 85)">question3.手写<span>promise</span></h3>
    <br />
    <h5>从JavaScript 执行机制开始</h5>
    <van-button plain type="primary" @click="question4()"
      >执行机制测试</van-button
    >
    <h5>Promise相关习题</h5>
    <van-button plain type="primary" @click="question3()">测试</van-button>
    <!-- question3()里面的代码块注释里是题目，行注释里是运行结果。题目从上到下由简单到复杂。 -->
    <!-- 习题来自 微信公众号：前端阳光 -->
     <h4>手写Promise</h4>
     从这里开始实现自己的promise
  </div>
</template>

<script>
import { Button } from "vant";
export default {
  name: "App",
  components: {
    [Button.name]: Button,
  },
  methods: {
    question3() {
      /*  const promise1 = new Promise((resolve, reject) => {
        console.log("promise1");
      });
			console.log("1", promise1); */
      //'promise1'
      //'1' Promise{<pending>}
      /*  const promise1 = new Promise((resolve, reject) => {
        console.log("promise1");
        resolve("resolve1");
      });
      const promise2 = promise1.then((res) => {
        console.log(res);
      });
      console.log("1", promise1);
      console.log("2", promise2);  */
      //'promise1'
      //'1' Promise{<resolved>: 'resolve1'}
      //'2' Promise{<pending>}
      //'resolve1'
      /*   const fn = () =>
        new Promise((resolve, reject) => {
          console.log(1);
          resolve("success");
        });
      fn().then((res) => {
        console.log(res);
      });
      console.log("start"); */
      //	1
      //'start'
      //'success'
      /*  const fn = () =>
        new Promise((resolve, reject) => {
          console.log(1);
          resolve("success");
        });
      console.log("start");
      fn().then((res) => {
        console.log(res);
      }); */
      //"start"
      //1
      //"success"
      /* console.log("start");
      setTimeout(() => {
        console.log("time");
      });
      Promise.resolve().then(() => {
        console.log("resolve");
      });
      console.log("end"); */
      //'start'
      //'end'
      //'resolve'
      //'time'
      /*  const promise1 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve("success");
          console.log("timer1");
        }, 1000);
        console.log("promise1里的内容");
      });
      const promise2 = promise1.then(() => {
        throw new Error("error!!!");
      });
      console.log("promise1", promise1);
      console.log("promise2", promise2);
      setTimeout(() => {
        console.log("timer2");
        console.log("promise1", promise1);
        console.log("promise2", promise2);
			}, 2000); */
      // 'promise1里的内容'
      // 'promise1' Promise{<pending>}
      // 'promise2' Promise{<pending>}
      // 'timer1'
      // test5.html:102 Uncaught (in promise) Error: error!!! at test.html:102
      // 'timer2'
      // 'promise1' Promise{<resolved>: "success"}
      // 'promise2' Promise{<rejected>: Error: error!!!}
      /*  const promise = new Promise((resolve, reject) => {
        resolve("success1");
        reject("error");
        resolve("success2");
      });
      promise
        .then((res) => {
          console.log("then: ", res);
        })
        .catch((err) => {
          console.log("catch: ", err);
				}); */
      //"then: success1"
      /*  const promise = new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log("timer");
          resolve("success");
        }, 1000);
      });
      const start = Date.now(); //1603871381305

      promise.then((res) => {
        console.log(res, Date.now() - start);
      });
      promise.then((res) => {
        console.log(res, Date.now() - start);
      }); */
      //'timer'
      //success 1001
      //success 1002
      /* Promise.resolve(1)
        .then(2)
        .then(Promise.resolve(3))
				.then(console.log); */
      //1
      /*  Promise.resolve()
        .then(
          function success(res) {
            throw new Error("error!!!");
          },
          function fail1(err) {
            console.log("fail1", err);
          }
        )
        .catch(function fail2(err) {
          console.log("fail2", err);
        }); */
      //fail2 Error: error!!!
      //	at success
      /* 			Promise.resolve('1')
  .then(res => {
    console.log(res)
  })
  .finally(() => {
    console.log('finally')
  })
Promise.resolve('2')
  .finally(() => {
    console.log('finally2')
  	return '我是finally2返回的值'
  })
  .then(res => {
    console.log('finally2后面的then函数', res)
	}) */
      // 	'1'
      // 'finally2'
      // 'finally'
      // 'finally2后面的then函数' '2'
      /* 			function promise1 () {
  let p = new Promise((resolve) => {
    console.log('promise1');
    resolve('1')
  })
  return p;
}
function promise2 () {
  return new Promise((resolve, reject) => {
    reject('error')
  })
}
promise1()
  .then(res => console.log(res))
  .catch(err => console.log(err))
  .finally(() => console.log('finally1'))

promise2()
  .then(res => console.log(res))
  .catch(err => console.log(err))
	.finally(() => console.log('finally2')) */
      // 	'promise1'
      // '1'
      // 'error'
      // 'finally1'
      // 'finally2'
      /*  function runAsync(x) {
        const p = new Promise((r) =>
          setTimeout(() => r(x, console.log(x)), 1000)
        );
        return p;
      }
      function runReject(x) {
        const p = new Promise((res, rej) =>
          setTimeout(() => rej(`Error: ${x}`, console.log(x)), 1000 * x)
        );
        return p;
      }
      Promise.all([runAsync(1), runReject(4), runAsync(3), runReject(2)])
        .then((res) => console.log(res))
				.catch((err) => console.log(err)); */
      // 				1
      // 3
      // // 2s后输出
      // 2
      // Error: 2
      // // 4s后输出
      // 4
      /*   function runAsync(x) {
        const p = new Promise((r) =>
          setTimeout(() => r(x, console.log(x)), 1000)
        );
        return p;
      }
      Promise.race([runAsync(1), runAsync(2), runAsync(3)])
        .then((res) => console.log("result: ", res))
				.catch((err) => console.log(err)); */
      // 				1
      // 'result: ' 1
      // 2
      // 3
      /*  async function async1() {
        console.log("async1 start");
        await async2();
        console.log("async1 end");
      }

      async function async2() {
        console.log("async2");
      }

      console.log("script start");

      setTimeout(function() {
        console.log("setTimeout");
      }, 0);

      async1();

      new Promise(function(resolve) {
        console.log("promise1");
        resolve();
      }).then(function() {
        console.log("promise2");
      });
      console.log("script end"); */
      //       'script start'
      // 'async1 start'
      // 'async2'
      // 'promise1'
      // 'script end'
      // 'async1 end'
      // 'promise2'
      // 'setTimeout'
      /* async function testSometing() {
        console.log("执行testSometing");
        return "testSometing";
      }

      async function testAsync() {
        console.log("执行testAsync");
        return Promise.resolve("hello async");
      }

      async function test() {
        console.log("test start...");
        const v1 = await testSometing();
        console.log(v1);
        const v2 = await testAsync();
        console.log(v2);
        console.log(v1, v2);
      }

      test();

      var promise = new Promise((resolve) => {
        console.log("promise start...");
        resolve("promise");
      });
      promise.then((val) => console.log(val));

      console.log("test end..."); */
      //       'test start...'
      // '执行testSometing'
      // 'promise start...'
      // 'test end...'
      // 'testSometing'
      // '执行testAsync'
      // 'promise'
      // 'hello async'
      // 'testSometing' 'hello async'
      /*   async function async1() {
        try {
          await Promise.reject("error!!!");
        } catch (e) {
          console.log(e);
        }
        console.log("async1");
        return Promise.resolve("async1 success");
      }
      async1().then((res) => console.log(res));
      console.log("script start"); */
      /*  const first = () =>
        new Promise((resolve, reject) => {
          console.log(3);
          let p = new Promise((resolve, reject) => {
            console.log(7);
            setTimeout(() => {
              console.log(5);
              resolve(6);
              console.log(p);
            }, 0);
            resolve(1);
          });
          resolve(2);
          p.then((arg) => {
            console.log(arg);
          });
        });

      first().then((arg) => {
        console.log(arg);
      });
      console.log(4); */
      /*   const async1 = async () => {
        console.log("async1");
        setTimeout(() => {
          console.log("timer1");
        }, 2000);
        await new Promise((resolve) => {
          console.log("promise1");
        });
        console.log("async1 end");
        return "async1 success";
      };
      console.log("script start");
      async1().then((res) => console.log(res));
      console.log("script end");
      Promise.resolve(1)
        .then(2)
        .then(Promise.resolve(3))
        .catch(4)
        .then((res) => console.log(res));
      setTimeout(() => {
        console.log("timer2");
      }, 1000); */
      /*   const p1 = new Promise((resolve) => {
        setTimeout(() => {
          resolve("resolve3");
          console.log("timer1");
        }, 0);
        resolve("resovle1");
        resolve("resolve2");
      })
        .then((res) => {
          console.log(res);
          setTimeout(() => {
            console.log(p1);
          }, 1000);
        })
        .finally((res) => {
          console.log("finally", res);
        }); */
      /* 'resolve1'
        'finally' undefined
        'timer1'
        Promise{<resolved>: undefined} 
        这个输出现在还不懂为什么Promise对象是undefined*/
      /*  const arr = [1, 2, 3];
      arr.reduce((p, x) => {
        return p.then(() => {
          return new Promise((r) => {
            setTimeout(() => r(console.log(x)), 1000);
          });
        });
      }, Promise.resolve()); */
      // 使用Promise实现每隔1秒输出1,2,3
    /*   function red() {
        console.log("red");
      }
      function green() {
        console.log("green");
      }
      function yellow() {
        console.log("yellow");
      }
      const light = function(timer, cb) {
        return new Promise((resolve) => {
          setTimeout(() => {
            cb();
            resolve();
          }, timer);
        });
      };
      const step = function() {
        Promise.resolve()
          .then(() => {
            return light(3000, red);
          })
          .then(() => {
            return light(2000, green);
          })
          .then(() => {
            return light(1000, yellow);
          })
          .then(() => {
            return step();
          });
      };

      step(); */
     // 红灯3秒亮一次，黄灯2秒亮一次，绿灯1秒亮一次；如何让三个灯不断交替重复亮灯？（用Promise实现）三个亮灯函数已经存在：
    },
    question4() {
      /* let data =[]
	  	$.ajax({
	  		url:"www.javascript.com",
	  		data:data,
	  		success:()=>{
	  			console.log("发送成功！")
	  		}
	  	})
	  	console.log("代码执行结束") */
      //代码执行结束
      //发送成功！
      /* setTimeout(() => {
	  		console.log('setTimeout')
	  	})
	  	new Promise((resolve) => {
	  		console.log('promise')
	  		resolve()
	  	}).then(() => {
	  		console.log('then')
	  	})
	  	console.log('console') */
      //promise
      //console
      //then
      //setTimeout

      //下面这段代码中process必须依赖node所以放在了vue项目里
      //运行结果参考https://mp.weixin.qq.com/s?__biz=MzU5NDM5MDg1Mw==&mid=2247483862&idx=1&sn=628b274a6828c9784cb10e1b53ccb952&chksm=fe00bbfcc97732ea5e5e7d2a77386a688e6aa15b9353c585d25204b27679eb84e77b81057ba6&scene=21#wechat_redirect
      console.log("1");

      setTimeout(function() {
        console.log("2");
        process.nextTick(function() {
          console.log("3");
        });
        new Promise(function(resolve) {
          console.log("4");
          resolve();
        }).then(function() {
          console.log("5");
        });
      });
      process.nextTick(function() {
        console.log("6");
      });
      new Promise(function(resolve) {
        console.log("7");
        resolve();
      }).then(function() {
        console.log("8");
      });

      setTimeout(function() {
        console.log("9");
        process.nextTick(function() {
          console.log("10");
        });
        new Promise(function(resolve) {
          console.log("11");
          resolve();
        }).then(function() {
          console.log("12");
        });
      });
    },
  },
};
</script>

<style>
#app {
  padding: 15px; 
}
</style>
